import com.fasterxml.jackson.annotation.JacksonAnnotationValue;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import kotlinx.datetime.Clock;
import org.jetbrains.annotations.NotNull;
import org.mozilla.javascript.NativeConsole;



import java.util.Random;
import java.security.SecureRandom;

import java.io.*;
import java.net.*;


import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
//import com.intellij.ide;

public class SearchUpAction extends AnAction {
    
    @Override
    public void actionPerformed(@NotNull AnActionEvent event) {
        // 执行操作时显示对话框
        //Messages.showInfoMessage("Hello from Custom Action---SearchUpAction!", "Plugin Action");




        qbs04_util util_tool = new  qbs04_util();
        //com.intellij.ide.util

        //PropertiesComponent.GetInstance().getValue()

        // Get all the required data from data keys
        Editor editor = event.getData(CommonDataKeys.EDITOR);
        if (editor == null) return;
        Project project = event.getData(CommonDataKeys.PROJECT);
        if (project == null) return;
        Document document = editor.getDocument();
        //得到文件的总行数
        int cur_linecount = document.getLineCount();



        //Clock.if (Constants.debug_mode) System.out.printf("%d \n" ,  cur_linecount);
        //new NativeConsole.ConsolePrinter().print();
        if (Constants.debug_mode) System.out.println("-----");
        //println("sfsadf");
        if (Constants.debug_mode) System.out.printf("%d \n" ,  cur_linecount);



        if (editor != null) {
            //得到位置信息, 如果选中了部分文本, 以选中文本尾为准
            int line = editor.getCaretModel().getLogicalPosition().line;
            int column = editor.getCaretModel().getLogicalPosition().column;
            // 处理位置信息
            if (Constants.debug_mode) System.out.printf("   %d  %d \n" ,  line, column);

            String start_string_id = "(%%";
            String end_string_id = "%%)";
            int end_pos = -1;
            int start_pos = -1;

            //得到文件的总行数
            int 文件的总长度 = document.getTextLength();
            //对于大文件可以设置为 10240 40960 ...
            int 每次进行查找时的块大小 = 4096;
            // 1. 如果光标正好在 (%% 的内部, 考虑这种情况
            // 2. -1 , 是避免 光标正好在 (%% 顶部, 连续进行 up search, 会始终找到这个
            int overlap_size =  start_string_id.length() -1;
            
            String textToFind = null;
            int 预期的目标字符串的最大长度 = 1500;

            textToFind = start_string_id;
            if (textToFind != null && !textToFind.isEmpty()) {
                //取得当前位置
                int offset = editor.getCaretModel().getOffset();
                int search_start_pos_offset = 1;
                int search_end_pos_offset = 1;
                int cur_offset = offset;
                int 查找次数 = 0;
                while ( search_start_pos_offset > 0  ) {

                    search_start_pos_offset = cur_offset - 每次进行查找时的块大小;
                    if (search_start_pos_offset < 0) {
                        search_start_pos_offset = 0;
                    }
                    search_end_pos_offset = cur_offset + overlap_size;
                    if (search_end_pos_offset >= 文件的总长度) {
                        search_end_pos_offset = 文件的总长度 - 1;
                    }

                    if (search_start_pos_offset < search_end_pos_offset) {

                        String 进行搜索的字符串 = editor.getDocument().getText(new TextRange(search_start_pos_offset, search_end_pos_offset));
                        int 最后一次出现的位置 = 进行搜索的字符串.lastIndexOf(textToFind);
                        if (最后一次出现的位置 >= 0) {
                            //找到了
                            //int 在全文中的位置 = search_start_pos_offset + 最后一次出现的位置;
                            start_pos = search_start_pos_offset + 最后一次出现的位置;
                            break;

                        } else {
                            //没有找到

                        }

                    } else {
                        //没有找到: 实际上就是不存在这样的情况

                    }

                    cur_offset =  search_start_pos_offset;
                    查找次数 ++;
                    if (Constants.debug_mode) System.out.printf("查找次数 %d " ,  查找次数);
                } //while()
                // found start id, now, try to find end id
                if (start_pos >= 0) {
                    int end_offset = start_pos + 预期的目标字符串的最大长度;
                    if (end_offset >= 文件的总长度){ end_offset = 文件的总长度 - 1;}
                    String 进行搜索的字符串 = editor.getDocument().getText(new TextRange(start_pos, end_offset));
                    int here_offset = 进行搜索的字符串.indexOf( end_string_id);
                    if ( here_offset >= 0){
                        //找到了
                        end_pos = start_pos + here_offset + end_string_id.length();
                    }else{
                        //没有找到

                    }
                }

                String target_str = null;
                if (true) {
                    if (Constants.debug_mode) System.out.printf("start end:%d %d\n", start_pos, end_pos);
                    if ((end_pos >= 0) && (start_pos >= 0) && (start_pos < end_pos)) {

                        target_str = document.getText(new TextRange(start_pos + start_string_id.length(), end_pos - end_string_id.length() ));
                        if (Constants.debug_mode) System.out.printf("target_str:%s\n", target_str);
                        editor.getCaretModel().moveToOffset(start_pos);
                        editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);

                        //return; //just for debug
                    } else {
                        if (Constants.debug_mode) System.out.printf("中止,因为不是一个有效的范围: start_pos:%d  end_pos:%d\n", start_pos,end_pos);
                        return;
                    }
                }else {

                }

                if (target_str != null) {

                    String str_to_qbs04 = target_str;
                    String hostname = "localhost";
                    int port = 27193;

                    // 使用try-with-resources确保资源自动关闭
                    try {
                        Socket socket = new Socket(hostname, port);

                         socket.setSoTimeout(6000);  //6秒超时
                         PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                         BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()) );

                        if (Constants.debug_mode) System.out.println("已连接到服务器: " + socket.getInetAddress());

                        // 向服务器发送消息
                        out.println(str_to_qbs04);
                        //if (Constants.debug_mode) System.out.println("已向服务器发送问候。");
                        if (Constants.debug_mode) System.out.printf("已向服务器发送:%s\n", str_to_qbs04);



                    } catch (UnknownHostException e) {
                        System.err.println("无法找到服务器主机: " + e.getMessage());
                    } catch (IOException e) {
                        System.err.println("与服务器通信时发生I/O错误: " + e.getMessage());
                    }

                }else{
                    Messages.showInfoMessage("UP: can not find target string!", "Plugin Up Action");

                }


            }






        }
        // remove it , it is ok, only reference
         if (false) {
             // 方法1：通过 PsiFile 获取
             PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());

             if (psiFile != null) {
                 String fileName = psiFile.getName();
                 Messages.showInfoMessage("当前文件名: " + fileName, "文件信息");
             }
         }








        if (false) {


            // Work off of the primary caret to get the selection info
            Caret primaryCaret = editor.getCaretModel().getPrimaryCaret();
            int start = primaryCaret.getSelectionStart();
            int end = primaryCaret.getSelectionEnd();

            // Replace the selection with a fixed string.
            // Must do this document change in a write action context.
            WriteCommandAction.runWriteCommandAction(project, () ->
                    document.replaceString(start, end, "editor_basics")
            );

            // De-select the text range that was just replaced
            primaryCaret.removeSelection();
        }
    }
    
    @Override
    public void update(@NotNull AnActionEvent e) {
        // 根据上下文启用或禁用Action
        // 例如：只有在有项目打开时才启用
        boolean hasProject = e.getProject() != null;
        e.getPresentation().setEnabled(hasProject);
    }
    
    @Override
    public @NotNull ActionUpdateThread getActionUpdateThread() {
        // 在事件调度线程上执行update方法
        return ActionUpdateThread.EDT;
    }
}











